--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
  local fxtz_desc = [[
  ## 规则简介

  该模式为单挑模式，共有若干个天气效果与若干个变更时机，每局游戏将随机抽取其中6个天气与3个变更时机作为基础池。

  双方选择武将后，将进行天气的禁选。

  ---

  ## 天气的禁选

  1号位禁用一个天气效果，剩余的天气效果作为本局游戏的天气池。

  2号位从天气池中选择一个天气作为初始天气，初始天气在首轮结束时一定会变更。

  ---

  ## 天气效果

  游戏开始时，将随机应用一个天气池中的天气效果。

  在符合特定条件后，将发生天气变更：用一个与当前天气不同的随机天气效果取代当前的天气。

  ---

  ## 变更时机

  游戏开始时，将随机应用一个时机池中的变更时机。

  每个变更时机具有不同的积蓄值，当累计触发的对应时机数达到积蓄值后，将发生天气变更，同时将追加应用时机池中一个新的变更时机。

  已应用的变更时机不会与未应用的区别显示。

  ---

  ## 天气一览

  <font size=2>快晴：未造成伤害的【杀】不计入次数限制，使用的【杀】造成伤害后摸两张牌。</font>

  <font size=2>苍天：使用【杀】无次数限制且结算结束后随机重铸一张非【杀】手牌。</font>

  <font size=2>浓雾：造成伤害后增加1点体力上限，然后回复1点体力值。</font>

  <font size=2>花云：成为【杀】的目标后，可以弃置一张手牌取消之。</font>

  <font size=2>川雾：一张牌结算结束后双方距离+1，若当前已为+1，下次变为-1。</font>

  <font size=2>台风：不可响应牌，准备阶段摸一张牌，出牌阶段使用【杀】的次数+1。</font>

  <font size=2>雪：受到伤害时，若已受伤则防止此伤害并失去1点体力上限。</font>

  <font size=2>太阳雨：受到牌的伤害后随机弃置一张不同类型的牌。</font>

  <font size=2>疏雨：受到或造成伤害后，将手牌随机调整至四张。</font>

  <font size=2>风雨：每回合首个判定阶段前执行一个额外的出牌阶段，此阶段与对方距离视为1。</font>

  <font size=2>钻石尘：每回合首次进入濒死状态时失去1点体力。</font>

  <font size=2>烈日：回合结束时，若未于本回合造成过伤害，失去1点体力。</font>

  ---

  ## 时机及积蓄值一览

  <font size=2>造成伤害后：积蓄值4</font>

  <font size=2>受到伤害后：积蓄值3</font>

  <font size=2>回合开始时：积蓄值3</font>

  <font size=2>失去装备区的牌后：积蓄值2</font>

  <font size=2>每轮结束时：积蓄值2</font>

  <font size=2>一张手牌被弃置后：积蓄值5</font>

  <font size=2>判定后：积蓄值2</font>

  <font size=2>回复体力后：积蓄值3</font>

  <font size=2>使用伤害类牌后：积蓄值5</font>

  <font size=2>摸牌后：积蓄值5</font>

]]

  local fxtz_timing_table = {
    ["fxtz_timing1"] = 4,
    ["fxtz_timing2"] = 3,
    ["fxtz_timing3"] = 3,
    ["fxtz_timing4"] = 2,
    ["fxtz_timing5"] = 2,
    ["fxtz_timing6"] = 5,
    ["fxtz_timing7"] = 2,
    ["fxtz_timing8"] = 3,
    ["fxtz_timing9"] = 5,
    ["fxtz_timing10"] = 5,
  }

  ---@param room Room
  ---@param log string
  local function Toast(room, log)
    room:sendLog({
      type = log,
      toast = true
    })
  end
  ---设置天气
  ---@param room Room
  ---@param weather string
  local function SetWeather(room, weather)
    room:setBanner("fxtz_init_weather", 0)
    room:setBanner("@[:]fxtz_current_effect", weather)
    if weather == "river_mist" then
      room:setBanner("@river_mist", "0")
    else
      room:setBanner("@river_mist", 0)
    end
  end
  ---改变天气
  ---@param room Room
  local function ChangeWeather(room)
    local current = room:getBanner("@[:]fxtz_current_effect")
    local weathers = room:getBanner("@[:]fxtz_effects")
    table.removeOne(weathers, current)
    local prefix = room:getBanner("fxtz_init_weather") == 1 and "fxtz_weather_change_init" or "fxtz_weather_change"
    SetWeather(room, table.random(weathers))
    Toast(room, Fk:translate(prefix) .. Fk:translate(room:getBanner("@[:]fxtz_current_effect")))
    room:delay(2500)
  end
  ---设置积蓄值
  ---@param room Room
  ---@param key string
  ---@param value integer|string
  local function SetEffect(room, key, value)
    if type(value) == "number" then
      value = tostring(value)
    end
    room:setBanner(key, value)
  end
  ---增减积蓄值
  ---@param room Room
  ---@param key string
  ---@param value integer
  local function ChargeEffect(room, key, value)
    local current = room:getBanner(key)
    if current == nil then
      return
    else
      current = tonumber(current)
    end
    current = current + value
    if current >= fxtz_timing_table[key] then
      ChangeWeather(room)
      current = 0
      local timings = room:getBanner("@[:]fxtz_timing")
      local timings_invalid = {}
      for _, str in ipairs(timings) do
        if room:getBanner(str) == nil then
          table.insertIfNeed(timings_invalid, str)
        end
      end
      if #timings_invalid > 0 then
        SetEffect(room, table.random(timings_invalid), 0)
      end
    end
    SetEffect(room, key, current)
  end

  local fxtz_mode = fk.CreateGameMode {
    name = "fxtz_mode",
    minPlayer = 2,
    maxPlayer = 2,
    logic = function()
      local fxtz_logic = GameLogic:subclass("fxtz_logic")

      function fxtz_logic:chooseGenerals()
        local room = self.room
        local generalNum = room:getSettings('generalNum')
        local n = room:getSettings('enableDeputy') and 2 or 1
        local players = table.simpleClone(room.players)
        room:setCurrent(players[1])

        local generals = table.random(room.general_pile, #players * generalNum)

        local req = Request:new(players, "AskForGeneral")
        for i, p in ipairs(players) do
          local arg = table.slice(generals, (i - 1) * generalNum + 1, i * generalNum + 1)
          req:setData(p, { arg, n })
          req:setDefaultReply(p, table.random(arg, n))
        end

        for _, p in ipairs(players) do
          local result = req:getResult(p)
          local general, deputy = result[1], result[2]
          room:prepareGeneral(p, general, deputy)
        end

        room:askToChooseKingdom(players)
      end

      function fxtz_logic:action()
        local all_weathers = { "fine_weather", "blue_sky", "heavy_fog", "flower_cloud", "river_mist", "typhoon", "snow", "sun_shower", "light_rain", "wind_and_rain", "diamond_dust", "heat_wave" }
        local weathers = table.random(all_weathers, 6)
        local valid_weather = table.clone(weathers)
        local room = self.room
        local ban1_w = room:askToChoice(room.players[1], {
          choices = valid_weather,
          skill_name = "fxtz_ban_weather",
          prompt = "fxtz_ban_weather_prompt",
          detailed = true,
        })
        table.removeOne(valid_weather, ban1_w)
        Toast(room, room.players[1].serverplayer:getScreenName() .. Fk:translate("fxtz_ban_weather_result") .. Fk:translate(ban1_w))
        room:delay(2500)
        -- local ban2_w = room:askToChoice(room.players[2], {
        --   choices = valid_weather,
        --   skill_name = "fxtz_ban_weather",
        --   prompt = "fxtz_ban_weather_prompt",
        --   all_choices = weathers,
        --   detailed = true,
        -- })
        -- table.removeOne(valid_weather, ban2_w)
        -- Toast(room, room.players[2].serverplayer:getScreenName() .. Fk:translate("fxtz_ban_weather_result") .. Fk:translate(ban2_w))
        local pick2_w = room:askToChoice(room.players[2], {
          choices = valid_weather,
          skill_name = "fxtz_pick_weather",
          prompt = "fxtz_pick_weather_prompt",
          detailed = true,
        })
        Toast(room, room.players[2].serverplayer:getScreenName() .. Fk:translate("fxtz_pick_weather_result") .. Fk:translate(pick2_w))
        room:delay(2500)
        room:setBanner("@[:]fxtz_effects", valid_weather)
        SetWeather(room, pick2_w)
        room:setBanner("fxtz_init_weather", 1)

        local all_timings = { "fxtz_timing1", "fxtz_timing2", "fxtz_timing3", "fxtz_timing4", "fxtz_timing5", "fxtz_timing6", "fxtz_timing7", "fxtz_timing8", "fxtz_timing9", "fxtz_timing10" }
        local timings = table.random(all_timings, 3)
        -- local valid_timing = table.clone(timings)
        -- local ban2_t = room:askToChoice(room.players[2], {
        --   choices = valid_timing,
        --   skill_name = "fxtz_ban_timing",
        --   prompt = "fxtz_ban_timing_prompt",
        --   all_choices = timings,
        --   detailed = true,
        -- })
        -- table.removeOne(valid_timing, ban2_t)
        -- Toast(room, room.players[2].serverplayer:getScreenName() .. Fk:translate("fxtz_ban_timing_result") .. Fk:translate(ban2_t))
        -- room:delay(2500)
        -- local ban1_t = room:askToChoice(room.players[1], {
        --   choices = valid_timing,
        --   skill_name = "fxtz_ban_timing",
        --   prompt = "fxtz_ban_timing_prompt",
        --   all_choices = timings,
        --   detailed = true,
        -- })
        -- table.removeOne(valid_timing, ban1_t)
        -- Toast(room, room.players[1].serverplayer:getScreenName() .. Fk:translate("fxtz_ban_timing_result") .. Fk:translate(ban1_t))
        -- room:delay(2500)
        -- if room:askToSkillInvoke(room.players[2], {
        --       skill_name = "fxtz_reroll_timing",
        --       prompt = "fxtz_reroll_timing_prompt:::" .. table.concat(table.map(timings, function(v)
        --         return Fk:translate(v)
        --       end), ",")
        --     }) then
        --   for _, cur in ipairs(timings) do
        --     table.removeOne(all_timings, cur)
        --   end
        --   timings = table.random(all_timings, 3)
        -- end
        local timing = table.random(timings)
        SetEffect(room, timing, 0)
        room:setBanner("@[:]fxtz_timing", timings)
        -- room:setBanner("@fxtz_timing_charge", "0/" .. fxtz_timing_table[timing])

        self:trigger(fk.GamePrepared)
        GameEvent.DrawInitial:create():exec()
        while true do
          GameEvent.Round:create():exec()
          if room.game_finished then break end
          if table.every(room.players, function(p) return p.dead and p.rest == 0 end) then room:gameOver("") end
          room:setCurrent(room.players[1])
        end
      end

      return fxtz_logic
    end,
    rule = "fxtz_rule",
    surrender_func = function(self, playedTime)
      return { { text = "", passed = true, } }
    end
  }

  local fxtz_rule = fk.CreateSkill {
    name = "fxtz_rule",
  }
  ---初始天气效果
  -- fxtz_rule:addEffect(fk.GamePrepared, {
  --   priority = 0.01,
  --   is_delay_effect = true,
  --   mute = true,
  --   can_trigger = Util.TrueFunc,
  --   on_use = function(self, event, target, player, data)
  --     local room = player.room
  --     local weathers = room:getBanner("@[:]fxtz_effects")
  --     local current = table.random(weathers)
  --     SetWeather(room, current)
  --   end
  -- })
  fxtz_rule:addEffect(fk.RoundEnd, {
    priority = 0.001,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return player.room:getBanner("fxtz_init_weather") == 1
    end,
    on_use = function(self, event, target, player, data)
      ChangeWeather(player.room)
    end
  })
  ---快晴：未造成伤害的【杀】不计入次数限制，使用的【杀】造成伤害后摸两张牌。
  fxtz_rule:addEffect(fk.CardUseFinished, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "fine_weather" then
        return false
      end
      if not data.from then
        return false
      end
      if data.from ~= player then
        return false
      end
      if data.card.trueName ~= "slash" then
        return false
      end
      if not data.damageDealt then
        return true
      end
      for p, v in pairs(data.damageDealt) do
        if v > 0 then
          return false
        end
      end
      return true
    end,
    on_use = function(self, event, target, player, data)
      if not data.extraUse then
        data.extraUse = true
        data.from:addCardUseHistory(data.card.trueName, -1)
      end
    end
  })
  fxtz_rule:addEffect(fk.Damage, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "fine_weather" then
        return false
      end
      if not data.from then
        return false
      end
      if not data.card then
        return false
      end
      if data.card.trueName ~= "slash" then
        return false
      end
      if data.from ~= player then
        return false
      end
      return true
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      room:drawCards(data.from, 2, "fine_weather")
    end
  })
  ---苍天：使用【杀】无次数限制且结算结束后随机重铸一张非【杀】手牌。
  fxtz_rule:addEffect(fk.CardUseFinished, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "blue_sky" then
        return false
      end
      return data.card.trueName == "slash" and data.from and data.from == player and table.any(player:getCardIds("h"), function(id)
        return Fk:getCardById(id).trueName ~= "slash"
      end)
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      local cards = table.filter(data.from:getCardIds("h"), function(id)
        return Fk:getCardById(id).trueName ~= "slash"
      end)
      room:recastCard(table.random(cards, 1), data.from, "blue_sky")
    end
  })
  fxtz_rule:addEffect("targetmod", {
    bypass_times = function(self, player, skill, scope, card, to)
      if Fk:currentRoom():getBanner("@[:]fxtz_current_effect") == "blue_sky" and card.trueName == "slash" then
        return true
      end
    end
  })
  ---浓雾：造成伤害后增加1点体力上限，然后回复1点体力值。
  fxtz_rule:addEffect(fk.Damage, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "heavy_fog" then
        return false
      end
      return data.from and data.from == player
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      room:changeMaxHp(player, 1)
      room:recover({
        who = player,
        num = 1,
      })
    end
  })
  ---花云：成为【杀】的目标后，可以弃置一张手牌取消之。
  fxtz_rule:addEffect(fk.TargetConfirmed, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "flower_cloud" then
        return false
      end
      return data.card.trueName == "slash" and data.to == player and #player:getCardIds("h") > 0
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      local cards = room:askToDiscard(player, {
        min_num = 1,
        max_num = 1,
        skill_name = "flower_cloud",
        prompt = "flower_cloud_prompt:::" .. data.card:toLogString()
      })
      if #cards > 0 then
        data:cancelCurrentTarget()
      end
    end
  })
  ---川雾：一张牌结算结束后双方距离+1，若当前已为+1，下次变为-1。
  fxtz_rule:addEffect(fk.CardUseFinished, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "river_mist" then
        return false
      end
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      local distance = tonumber(room:getBanner("@river_mist"))
      if distance == 1 then
        distance = -1
      else
        distance = distance + 1
      end
      room:setBanner("@river_mist", tostring(distance))
    end
  })
  fxtz_rule:addEffect("distance", {
    priority = 0.01,
    mute = true,
    correct_func = function(self, from, to)
      local room = Fk:currentRoom()
      if room:getBanner("@[:]fxtz_current_effect") == "river_mist" then
        return tonumber(room:getBanner("@river_mist"))
      end
    end
  })
  ---台风：不可响应牌，准备阶段摸一张牌，出牌阶段可以多出一张【杀】。
  fxtz_rule:addEffect(fk.EventPhaseStart, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "typhoon" then
        return false
      end
      return player == target and target.phase == Player.Start
    end,
    on_use = function(self, event, target, player, data)
      player.room:drawCards(player, 1, "typhoon")
    end
  })
  fxtz_rule:addEffect("targetmod", {
    priority = 0.01,
    mute = true,
    residue_func = function(self, player, skill, scope, card, to)
      if Fk:currentRoom():getBanner("@[:]fxtz_current_effect") == "typhoon" and card.trueName == "slash" and scope == Player.HistoryPhase and player.phase == Player.Play then
        return 1
      end
    end
  })
  fxtz_rule:addEffect(fk.PreCardUse, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "typhoon" then
        return false
      end
      return player == target
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      data.disresponsiveList = room:getAlivePlayers()
    end
  })
  ---雪：受到伤害时，若已受伤则防止此伤害并失去1点体力上限。
  fxtz_rule:addEffect(fk.DetermineDamageInflicted, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "snow" then
        return false
      end
      return player == target and player.hp < player.maxHp
    end,
    on_use = function(self, event, target, player, data)
      data:preventDamage()
      player.room:changeMaxHp(player, -1)
    end
  })
  ---太阳雨：受到牌的伤害后随机弃置一张不同类型的牌。
  fxtz_rule:addEffect(fk.Damaged, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "sun_shower" then
        return false
      end
      return target == player and data.card
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      local card_type = data.card.type
      local cards = table.filter(player:getCardIds("he"), function(id)
        return Fk:getCardById(id).type ~= card_type
      end)
      if #cards > 0 then
        room:throwCard(table.random(cards), "sun_shower", player)
      end
    end
  })
  ---疏雨：受到或造成伤害后，将手牌随机调整至四张。
  fxtz_rule:addEffect(fk.Damage, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "light_rain" then
        return false
      end
      return target == player and #player:getCardIds("h") ~= 4
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      if #player:getCardIds("h") > 4 then
        local cards = table.random(player:getCardIds("h"), #player:getCardIds("h") - 4)
        room:throwCard(cards, "light_rain", player, player)
      else
        room:drawCards(player, 4 - #player:getCardIds("h"), "light_rain")
      end
    end
  })
  fxtz_rule:addEffect(fk.Damaged, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "light_rain" then
        return false
      end
      return target == player and #player:getCardIds("h") ~= 4
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      if #player:getCardIds("h") > 4 then
        local cards = table.random(player:getCardIds("h"), #player:getCardIds("h") - 4)
        room:throwCard(cards, "light_rain", player, player)
      else
        room:drawCards(player, 4 - #player:getCardIds("h"), "light_rain")
      end
    end
  })
  ---钻石尘：进入濒死状态时失去1点体力。
  fxtz_rule:addEffect(fk.EnterDying, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "diamond_dust" then
        return false
      end
      return player == target and player:getMark("fxtz_diamond_dust-turn") == 0
    end,
    on_use = function(self, event, target, player, data)
      player.room:setPlayerMark(player, "fxtz_diamond_dust-turn", 1)
      player.room:loseHp(player, 1, "diamond_dust")
    end
  })
  ---烈日：回合结束时，若未于本回合造成过伤害，失去1点体力。
  fxtz_rule:addEffect(fk.TurnEnd, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "heat_wave" then
        return false
      end
      return player == target and player:getMark("@@fxtz_heat_wave-turn") == 0
    end,
    on_use = function(self, event, target, player, data)
      player.room:loseHp(player, 1, "heat_wave")
    end
  })
  fxtz_rule:addEffect(fk.Damage, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "heat_wave" then
        return false
      end
      return player == target and player:getMark("@@fxtz_heat_wave-turn") == 0
    end,
    on_use = function(self, event, target, player, data)
      player.room:setPlayerMark(player, "@@fxtz_heat_wave-turn", 1)
    end
  })
  ---风雨：每回合首个判定阶段前执行一个额外的出牌阶段，此阶段与对方距离视为1。
  fxtz_rule:addEffect(fk.TurnStart, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "wind_and_rain" then
        return false
      end
      return player == target
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      local phases = data.phase_table
      local done = false
      for index, phase in ipairs(phases) do
        if phase.phase == Player.Judge and not done then
          done = true
          table.insert(phases, index - 1, {
            who = player,
            phase = Player.Play,
            reason = "wind_and_rain",
          })
        end
      end
    end
  })
  fxtz_rule:addEffect(fk.EventPhaseStart, {
    priority = 0.01,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      if player.room:getBanner("@[:]fxtz_current_effect") ~= "wind_and_rain" then
        return false
      end
      return player == target and data.reason == "wind_and_rain"
    end,
    on_use = function(self, event, target, player, data)
      player.room:setPlayerMark(player, "fxtz_wind_and_rain-phase", 1)
    end
  })
  fxtz_rule:addEffect("distance", {
    fixed_func = function(self, from, to)
      if Fk:currentRoom():getBanner("@[:]fxtz_current_effect") == "wind_and_rain" and from:getMark("fxtz_wind_and_rain-phase") == 1 then
        return 1
      end
    end
  })
  ---造成伤害后：积蓄值5
  fxtz_rule:addEffect(fk.Damage, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing1", 1)
    end
  })
  ---受到伤害后：积蓄值5
  fxtz_rule:addEffect(fk.Damaged, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing2", 1)
    end
  })
  ---回合开始时：积蓄值3
  fxtz_rule:addEffect(fk.TurnStart, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing3", 1)
    end
  })
  ---失去装备区的牌后：积蓄值3
  fxtz_rule:addEffect(fk.AfterCardsMove, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      for _, move in ipairs(data) do
        if move.from then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerEquip then
              return player == move.from
            end
          end
        end
      end
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing4", 1)
    end
  })
  ---每轮结束时：积蓄值1
  fxtz_rule:addEffect(fk.RoundEnd, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing5", 1)
    end
  })
  ---一张手牌被弃置后：积蓄值7
  fxtz_rule:addEffect(fk.AfterCardsMove, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      for _, move in ipairs(data) do
        if move.from and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              return move.from == player
            end
          end
        end
      end
    end,
    on_use = function(self, event, target, player, data)
      local value = 0
      for _, move in ipairs(data) do
        if move.from and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand and move.from == player then
              value = value + 1
            end
          end
        end
      end
      ChargeEffect(player.room, "fxtz_timing6", value)
    end
  })
  ---判定后：积蓄值3
  fxtz_rule:addEffect(fk.FinishJudge, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing7", 1)
    end
  })
  ---回复体力后：积蓄值7
  fxtz_rule:addEffect(fk.HpRecover, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing8", 1)
    end
  })
  ---使用伤害类牌后：积蓄值5
  fxtz_rule:addEffect(fk.CardUseFinished, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      return target == player and data.card.is_damage_card
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing9", 1)
    end
  })
  ---摸牌后：积蓄值7
  fxtz_rule:addEffect(fk.AfterCardsMove, {
    priority = 0,
    is_delay_effect = true,
    mute = true,
    can_trigger = function(self, event, target, player, data)
      for _, move in ipairs(data) do
        if move.moveReason == fk.ReasonDraw and move.to then
          return move.to == player
        end
      end
    end,
    on_use = function(self, event, target, player, data)
      ChargeEffect(player.room, "fxtz_timing10", 1)
    end
  })

  extension:loadSkillSkels { fxtz_rule }
  extension:addGameMode(fxtz_mode)

  Fk:loadTranslationTable {
    ["fxtz_mode"] = "非想天则",
    [":fxtz_mode"] = fxtz_desc,

    ["fxtz_rule"] = "非想天则",
    ["fxtz_ban_weather"] = "天气禁用",
    ["fxtz_ban_weather_prompt"] = "请禁用一个天气效果",
    ["fxtz_ban_weather_result"] = "禁用了天气：",
    ["fxtz_pick_weather"] = "天气选取",
    ["fxtz_pick_weather_prompt"] = "请选择初始天气",
    ["fxtz_pick_weather_result"] = "选择了初始天气：",
    -- ["fxtz_ban_timing"] = "时机禁选",
    -- ["fxtz_ban_timing_prompt"] = "请禁用一个变更时机",
    -- ["fxtz_ban_timing_result"] = "禁用了时机：",
    ["fxtz_reroll_timing"] = "时机重抽",
    ["fxtz_reroll_timing_prompt"] = "你可以重抽触发时机（%arg）",
    ["fxtz_weather_change"] = "天气发生变更！当前天气：",
    ["fxtz_weather_change_init"] = "初始天气变更！当前天气：",

    ["@[:]fxtz_current_effect"] = "当前天气",
    ["@[:]fxtz_effects"] = "本局天气",
    ["@[:]fxtz_timing"] = "变更时机",
    ["@fxtz_timing_charge"] = "积蓄值",

    ["fine_weather"] = "快晴",
    [":fine_weather"] = "未造成伤害的【杀】不计入次数限制，使用的【杀】造成伤害后摸两张牌。",

    ["blue_sky"] = "苍天",
    [":blue_sky"] = "使用【杀】无次数限制且结算结束后随机重铸一张非【杀】手牌。",
    ["blue_sky_prompt1"] = "苍天：你可以使用一张【杀】",
    ["blue_sky_prompt2"] = "苍天：你须重铸一张牌",

    ["heavy_fog"] = "浓雾",
    [":heavy_fog"] = "造成伤害后增加1点体力上限，然后回复1点体力值。",

    ["flower_cloud"] = "花云",
    [":flower_cloud"] = "成为【杀】的目标后，可以弃置一张手牌取消之。",
    ["flower_cloud_prompt"] = "花云：你可以弃置一张手牌并取消成为%arg的目标",

    ["river_mist"] = "川雾",
    [":river_mist"] = "一张牌结算结束后双方距离+1，若当前已为+1，下次变为-1。",
    ["@river_mist"] = "川雾",

    ["typhoon"] = "台风",
    [":typhoon"] = "不可响应牌，准备阶段摸一张牌，出牌阶段可以多出一张【杀】。",

    ["snow"] = "雪",
    [":snow"] = "受到伤害时，若已受伤则防止此伤害并失去1点体力上限。",

    ["sun_shower"] = "太阳雨",
    [":sun_shower"] = "受到牌的伤害后随机弃置一张不同类型的牌。",

    ["light_rain"] = "疏雨",
    [":light_rain"] = "受到或造成伤害后，将手牌随机调整至四张。",
    ["light_rain_prompt"] = "疏雨：你须将手牌弃置至四张",

    ["wind_and_rain"] = "风雨",
    [":wind_and_rain"] = "每回合首个判定阶段前执行一个额外的出牌阶段，此阶段与对方距离视为1。",

    ["diamond_dust"] = "钻石尘",
    [":diamond_dust"] = "每回合首次进入濒死状态时失去1点体力。",

    ["heat_wave"] = "烈日",
    [":heat_wave"] = "回合结束时，若未于本回合造成过伤害，失去1点体力。",
    ["@@fxtz_heat_wave-turn"] = "烈日 达成",

    ["fxtz_timing1"] = "造成伤害后",
    [":fxtz_timing1"] = "积蓄值4",
    ["fxtz_timing2"] = "受到伤害后",
    [":fxtz_timing2"] = "积蓄值3",
    ["fxtz_timing3"] = "回合开始时",
    [":fxtz_timing3"] = "积蓄值3",
    ["fxtz_timing4"] = "失去装备区的牌后",
    [":fxtz_timing4"] = "积蓄值2",
    ["fxtz_timing5"] = "每轮结束时",
    [":fxtz_timing5"] = "积蓄值2",
    ["fxtz_timing6"] = "一张手牌被弃置后",
    [":fxtz_timing6"] = "积蓄值5",
    ["fxtz_timing7"] = "判定后",
    [":fxtz_timing7"] = "积蓄值2",
    ["fxtz_timing8"] = "回复体力后",
    [":fxtz_timing8"] = "积蓄值3",
    ["fxtz_timing9"] = "使用伤害类牌后",
    [":fxtz_timing9"] = "积蓄值5",
    ["fxtz_timing10"] = "摸牌后",
    [":fxtz_timing10"] = "积蓄值5",
  }
end
